package com.alquimia.identityaccess.infraestructura.config;

import com.alquimia.identityaccess.domain.model.UserId;
import com.alquimia.identityaccess.domain.model.UserRepository;
import com.alquimia.identityaccess.domain.model.User;
import org.hibernate.Query;
import org.hibernate.exception.ConstraintViolationException;

import java.util.UUID;

/**
 * Created by Ivo on 12/07/2014.
 */
public class HibernateUserRepository extends AbstractSessionHibernate implements UserRepository {

    @Override
    public void create(final User aUser) {
        try {
            this.session().saveOrUpdate(aUser);
        } catch (ConstraintViolationException e) {
            throw new IllegalStateException("El user no es único.", e);
        }
    }

    @Override
    public void update(final User aUser) {
        this.session().update(aUser);
    }

    @Override
    public void delete(final User aUser) {
        this.session().delete(aUser);
    }

    @Override
    public User userWithCredentials(final String aUsername, final String aEncryptedPassword) {
        Query query = this.session().createQuery(
                "from com.alquimia.identityaccess.domain.model.User as u "
                        + "where u.username = :username "
                        + "and u.password = :password"
        );

        query.setParameter("username", aUsername);
        query.setParameter("password", aEncryptedPassword);

        return (User) query.uniqueResult();
    }

    @Override
    public User withUsername(String aUsername) {

        Query query = this.session().createQuery(
                "from com.alquimia.identityaccess.domain.model.User as u "
                        + "where u.username = :username "
        );

        query.setParameter("username", aUsername);

        return (User) query.uniqueResult();
    }

    @Override
    public UserId nextIdentity() {
        return new UserId(UUID.randomUUID());
    }

    @Override
    public User userOfId(UserId aUserId) {
        Query query = this.session().createQuery(
                "from com.alquimia.identityaccess.domain.model.User as u "
                        + "where u.userId = :userId "
        );

        query.setParameter("userId", aUserId);

        return (User) query.uniqueResult();
    }
}
